package dryven.view.engine.component;

import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import dryven.view.ViewDataDictionary;
import dryven.view.engine.component.annotations.ChildZones;
import dryven.view.engine.component.annotations.ComponentStrategy;
import dryven.view.engine.component.childzone.ChildZoneBindings;
import dryven.view.engine.component.childzone.DefaultChildZoneStrategy;
import dryven.view.engine.component.metadata.MultiThreadRenderMethodDiscoverer;
import dryven.view.engine.component.metadata.MultiThreadStrategy;
import dryven.view.engine.parser.componentinvocation.AttributeBindings;

/**
 * A view component that should only be instanced once,
 * used multiply, even over multiple threads.
 * The attributes are also passed to the renderComponent
 * method, so 
 * @author bwindels
 *
 */

@ComponentStrategy(strategy = MultiThreadStrategy.class)
@ChildZones(strategy=DefaultChildZoneStrategy.class)

public abstract class MultiThreadViewComponent extends ViewComponent {

	@Override
	public void renderComponent(ViewDataDictionary localViewData, Writer out, ChildZoneBindings childZones, AttributeBindings attributes) {
		Method renderComponentMethod = new MultiThreadRenderMethodDiscoverer().getRenderMethod(getClass());
		try {
			//TODO pass real arguments and map annotations
			renderComponentMethod.invoke(this, null);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e.getCause());
		} catch (Exception e) {
			throw new RuntimeException("error while invoking method", e);
		} 
	}



}
